package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.*;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private DishMapper dishmapper;

    //新增套餐和套餐包含的菜品
    @Override
    @Transactional
    public void saveWithSetmealDishes(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        //向套餐表插入数据
        setmealMapper.insert(setmeal);
        //获取生成的套餐id
        Long setmealId = setmeal.getCategoryId();
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();

        setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealId));

        //保存套餐和菜品的关联关系
        setmealDishMapper.insertBatch(setmealDishes);
    }

    //根据id查询套餐和菜品
    @Override
    public SetmealVO getByIdWithDishes(Long id) {
        // 查询套餐信息
        Setmeal setmeal = setmealMapper.findById(id);
        //根据套餐id查询菜品数据
        List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealIds(id);
        //将查询到的数据封装到VO
        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);
        setmealVO.setSetmealDishes(setmealDishes);
        return setmealVO;
    }

    //修改套餐
    @Override
    public void updateWithDishes(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        //1、修改套餐表，执行update
        setmealMapper.update(setmeal);
        //2、删除套餐和菜品的关联关系，操作setmeal_dish表，执行delete
        setmealDishMapper.deleteBySetmealId(setmealDTO.getId());


        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        if (setmealDishes != null && setmealDishes.size() > 0) {
            setmealDishes.forEach(setmealDish -> {
                setmealDish.setDishId(setmealDTO.getId());
            });
            //3、重新插入套餐和菜品的关联关系，操作setmeal_dish表，执行insert
            setmealDishMapper.insertBatch(setmealDishes);
        }

    }

    //套餐分页查询
    @Override
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
     /*   PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());
        Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }*/
        int pageNum = setmealPageQueryDTO.getPage();
        int pageSize = setmealPageQueryDTO.getPageSize();

        PageHelper.startPage(pageNum, pageSize);
        Page<Setmeal> page = setmealMapper.pageQuery(setmealPageQueryDTO);
        List<Setmeal> setmealList = page.getResult();
        if (setmealList.isEmpty()) {
            return new PageResult(page.getTotal(), setmealList);
        }

        // 套餐分类名称
        // 获取查询套餐内所有的分类id
        List<Long> categoryIdList = setmealList.stream().map(Setmeal::getCategoryId).collect(Collectors.toList());
        // 去重
        Set<Long> categoryIds = new HashSet<>(categoryIdList);
        // 通过多个分类id查询相应的分类信息
        List<Category> categoryList = categoryMapper.findByIds(categoryIds);
        // 获取分类id对应的分类名称
        Map<Long, String> categoryMap = categoryList.stream().collect(Collectors.toMap(Category::getId, Category::getName));
        List<SetmealVO> list = new ArrayList<>();
        setmealList.stream().forEach(setmeal -> {
            SetmealVO vo = new SetmealVO();
            BeanUtils.copyProperties(setmeal, vo);
            String categoryName = categoryMap.get(setmeal.getCategoryId());
            vo.setCategoryName(categoryName);
            list.add(vo);
        });
        return new PageResult(page.getTotal(), list);
    }

    //批量删除套餐
   /* @Override
    public void deleteBatch(List<Long> ids) {
       //判断该套餐是否处于启售状态
        for (Long id : ids) {
            Setmeal setmeal = setmealMapper.getById(id);
            if (setmeal.getStatus() == StatusConstant.ENABLE) {
                //当前套餐处于起售中，不能删除
                throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
            }
        }
        //删除套餐
        for (Long id : ids) {
            setmealMapper.deleteById(id);
        }
    }*/
        @Transactional(rollbackFor = Exception.class)
        public void deleteBatch(List<Long> ids) {
            // 查出所有套餐，判断套餐，起售中的套餐无法删除
            List<Setmeal> list = setmealMapper.findByIds(ids);
            // 循环判断每个套餐，起售中的套餐无法删除
            for (Setmeal setmeal : list) {
                if (StatusConstant.ENABLE == setmeal.getStatus()) {
                    //起售中的套餐不能删除
                    throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
                }
            }
            // 删除套餐
            setmealMapper.delete(ids);
            // 根据套餐id删除套餐和菜品的关系
            setmealDishMapper.deleteBySetmealIds(ids);
        }

    @Override
   /* public void startOrStop(Integer status, Long id) {
        Setmeal setmeal = Setmeal.builder()
                .status(status)
                .id(id)
                .build();
        setmealMapper.update1(setmeal);
    }*/
    public void startOrStop(Integer status, Long setmealId) {
        // 起售套餐时，判断套餐内是否有停售菜品，有停售菜品提示 "套餐内包含未启售菜品，无法启售"
        if (StatusConstant.ENABLE.equals(status)) {
            // 根据套餐id查询 套餐对应的菜品有哪些
            List<SetmealDish> setmealDishList = setmealDishMapper.getBySetmealIds(setmealId);
            List<Long> dishIds = setmealDishList.stream().map(SetmealDish::getDishId).collect(Collectors.toList());
            List<Dish> list = dishmapper.findByIds(dishIds);
            for (Dish dish : list) {
                // 只要有菜品是停售状态的 套餐就不能起售
                if (StatusConstant.DISABLE.equals(dish.getStatus())) {
                    throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
                }
            }
        }
        // 更新套餐状态
        Setmeal setmeal = Setmeal.builder().id(setmealId).status(status).build();
        setmealMapper.update(setmeal);
    }




    //用户端

    /**
     * 条件查询
     *
     * @param setmeal
     * @return
     */
    public List<Setmeal> list(Setmeal setmeal) {
        List<Setmeal> list = setmealMapper.list(setmeal);
        return list;
    }


    /**
     * 根据id查询菜品选项
     *
     * @param id
     * @return
     */
    public List<DishItemVO> getDishItemById(Long id) {
        return setmealMapper.getDishItemBySetmealId(id);
    }
}

